﻿using Core.Domain.Entities;
using Core.Domain.Enums;
using Finbuckle.MultiTenant;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Infrastructure.Persistence.Configurations;

public class UserConfiguration : IEntityTypeConfiguration<User>
{
    public void Configure(EntityTypeBuilder<User> builder)
    {
        // builder.IsMultiTenant();

        builder
            .ToTable("Users", "identity")
            .IsMultiTenant();

        // 1. 主键
        builder.HasKey(u => u.Id);

        // 2. 值对象映射
        builder.OwnsOne(u => u.Avatar, a =>
        {
            a.Property(av => av.Url).HasColumnName("AvatarUrl").HasMaxLength(512).IsRequired(false);
            a.Property(av => av.ContentType).HasColumnName("AvatarContentType").HasMaxLength(64).IsRequired(false);
        });

        builder.OwnsOne(u => u.PhoneNumber, p =>
        {
            p.Property(n => n.Value).HasColumnName("PhoneNumber").HasMaxLength(32);
        });

        builder.OwnsOne(u => u.Lockout, l =>
        {
            l.Property(lo => lo.AccessFailedCount).HasColumnName("AccessFailedCount").HasDefaultValue(0);
            l.Property(lo => lo.LockoutEnd).HasColumnName("LockoutEnd").IsRequired(false);
            l.Ignore(lo => lo.IsLocked);
        });

        // 3. 字段约束
        builder.Property(u => u.Username).HasMaxLength(64).IsRequired(false);
        builder.HasIndex(u => u.NormalizedUserName);
        builder.Property(u => u.NormalizedUserName).HasMaxLength(64).IsRequired(false);

        builder.Property(u => u.Email).HasMaxLength(256).IsRequired(false);
        builder.HasIndex(u => u.NormalizedEmail);
        builder.Property(u => u.NormalizedEmail).HasMaxLength(256).IsRequired(false);

        builder.Property(u => u.PasswordHash).HasMaxLength(256).IsRequired(false);
        builder.Property(u => u.SecurityStamp).HasMaxLength(64).IsRequired(false);
        builder.Property(u => u.ConcurrencyStamp).IsConcurrencyToken().HasMaxLength(64).IsRequired(false);
        // 关键：将枚举映射为数据库中的字符串
        builder.Property(u => u.Gender)
       .HasConversion(
           v => v.ToString(),
           v => string.IsNullOrEmpty(v) ? null : (GenderType)Enum.Parse(typeof(GenderType), v))
       .HasMaxLength(20)
       .IsRequired(false);

        builder.Navigation(u => u.UserRoles)
            .HasField("_roles")
            .UsePropertyAccessMode(PropertyAccessMode.Field);

        // 4. 聚合内部集合（UserRole 作为值对象表）
        builder.HasMany(ur => ur.UserRoles)
               .WithOne(u => u.User)
               .HasForeignKey(u => u.UserId)
               .OnDelete(DeleteBehavior.Restrict);

        builder.HasMany(u => u.UserOrganizations)
            .WithOne()
            .HasForeignKey(uo => uo.UserId)
            .OnDelete(DeleteBehavior.Restrict);
    }
}
